﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;

using Game.Common;
using Game.Objects;
using Game.ResourceLocator;
using Game.Terrain;
using Game.Types;

namespace Game.Toolkit
{
    public static class StandardToolkit
    {
        public static Collection<TerrainType> TerrainTypes
        {
            get
            {
                var collection = 
                    new Collection<TerrainType>();
                collection = CollectTerrain(
                    typeof(StandardTerrain), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<TerrainType> CollectTerrain(
            Type type, Collection<TerrainType> collection)
        {
            PropertyInfo[] infos =  type.GetProperties();
            foreach (PropertyInfo info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                TerrainType v = obj as TerrainType;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static Collection<ObjectType> TerrainObjectTypes
        {
            get
            {
                Collection<ObjectType> collection = 
                    new Collection<ObjectType>();
                collection = CollectTerrainObjects(
                    typeof(StandardTerrainObjects), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<ObjectType> CollectTerrainObjects(
            Type type, Collection<ObjectType> collection)
        {
            PropertyInfo[] infos =  type.GetProperties();
            foreach (PropertyInfo info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                var v = obj as ObjectType;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static Collection<VehicleType> Vehicles
        {
            get
            {
                var collection = new Collection<VehicleType>();
                collection = CollectVehicles(
                    typeof(StandardVehicles), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<VehicleType> CollectVehicles(
            Type type, Collection<VehicleType> collection)
        {
            var infos =  type.GetProperties();
            foreach (var info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                var v = obj as VehicleType;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static Collection<GameObjectGroup> LargeObjects
        {
            get
            {
                Collection<GameObjectGroup> collection = 
                    new Collection<GameObjectGroup>();
                collection = CollectLargeObject(
                    typeof(StandardMountian), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<GameObjectGroup> CollectLargeObject(
            Type type, Collection<GameObjectGroup> collection)
        {
            PropertyInfo[] infos =  type.GetProperties();
            foreach (PropertyInfo info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                GameObjectGroup v = obj as GameObjectGroup;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static Collection<GameObjectGroup> BuildingObjects
        {
            get
            {
                Collection<GameObjectGroup> collection = 
                    new Collection<GameObjectGroup>();
                collection = CollectBuildingObject(
                    typeof(StandardBuildings), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<GameObjectGroup> MountianObjects
        {
            get
            {
                Collection<GameObjectGroup> collection = 
                    new Collection<GameObjectGroup>();
                collection = CollectBuildingObject(
                    typeof(StandardMountian), 
                    collection);
                return collection;
            }
        }
        
        public static Collection<GameObjectGroup> CollectBuildingObject(
            Type type, Collection<GameObjectGroup> collection)
        {
            PropertyInfo[] infos =  type.GetProperties();
            foreach (PropertyInfo info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                GameObjectGroup v = obj as GameObjectGroup;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static Collection<MapItemType> All
        {
            get
            {
                Collection<MapItemType> collection = new Collection<MapItemType>();
                collection = Collect(typeof(StandardVehicles), collection);
                collection = Collect(typeof(StandardTerrainObjects), collection);
                return collection;
            }
        }
        
        public static Collection<MapItemType> Collect(Type type,
                                                      Collection<MapItemType> collection)
        {
            PropertyInfo[] infos =  type.GetProperties();
            foreach (PropertyInfo info in infos) 
            {
                object obj = info.GetValue(type, new object[]{});
                MapItemType v = obj as MapItemType;
                if (v != null)
                {
                    collection.Add(v);
                }
            }
            
            return collection;
        }
        
        public static void RegisterResources()
        {
            AiPlayer.Register();
            HumanPlayer.Register();
            
            Collection<TerrainType> terrain = TerrainTypes;
            foreach(TerrainType item in terrain)
            {
                GameResourceLocator.Register(item);
            }
            
            Collection<VehicleType> vehicles = Vehicles;
            foreach(VehicleType item in vehicles)
            {
                GameResourceLocator.Register(item);
            }
            
            Collection<ObjectType> os = TerrainObjectTypes;
            foreach(ObjectType item in os)
            {
                GameResourceLocator.Register(item);
            }
            
            Collection<ObjectType> road = StandardInfrastructure.Railroad;
            foreach(MapItemType item in road)
            {
                GameResourceLocator.Register(item);
            }
            
            Collection<GameObjectGroup> buildingObjects = BuildingObjects;
            foreach (GameObjectGroup item in buildingObjects) 
            {
                GameResourceLocator.Register(item.BuildingType);

                List<GameObjectGroupPart> parts = item.Parts;
                foreach(GameObjectGroupPart part in parts)
                {
                    GameResourceLocator.Register(part.ObjectType);
                }
            }
            
            Collection<GameObjectGroup> mountianObjects = MountianObjects;
            foreach (GameObjectGroup item in mountianObjects) 
            {
                List<GameObjectGroupPart> parts = item.Parts;
                foreach(GameObjectGroupPart part in parts)
                {
                    GameResourceLocator.Register(part.ObjectType);
                }
            }
            
            GameResourceLocator.Register(StandardBuildings.HeadQuartersBuilding);
        }
        
        
    }
}
